import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.command.*;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.project.*;
import com.intellij.psi.*;
import com.intellij.psi.util.*;

import java.util.*;

/**
 * @author mizzle rain
 * @date 2020-11-03 16:45
 */
public class ConverterGenerate extends AnAction {
    @Override
    public void actionPerformed(AnActionEvent e) {
        Editor editor = e.getRequiredData(CommonDataKeys.EDITOR);
        Project project = e.getRequiredData(CommonDataKeys.PROJECT);
        PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
        Document document = editor.getDocument();
        // 获取插入符号模型
        Caret primaryCaret = editor.getCaretModel().getPrimaryCaret();
        // 获取插入符号位置的元素
        PsiElement element = psiFile.findElementAt(primaryCaret.getOffset());
        // 获取插入符号位置的方法
        PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);

        HashSet<String> fieldsSet = new HashSet<>();
        StringBuilder sb = new StringBuilder();
        // 获取方法参数的属性数组
        PsiParameter parameter = method.getParameterList().getParameter(0);
        PsiClass paraClass = PsiTypesUtil.getPsiClass(parameter.getType());
        PsiField[] paraFields = paraClass.getFields();
        for (PsiField f : paraFields) {
            fieldsSet.add(f.getName());
        }
        // 获取方法返回值的属性数组
        PsiType returnType = method.getReturnType();
        PsiClass retClass = PsiTypesUtil.getPsiClass(returnType);
        PsiField[] retFields = retClass.getFields();
        // 构造要插入的字符串
        for (PsiField f : retFields) {
            String name = f.getName();
            if (Objects.equals("serialVersionUID", name)) {
                continue;
            }
            String upperName = name.substring(0, 1).toUpperCase() + name.substring(1);
            if (fieldsSet.contains(name)) {
                sb.append(String.format("\t\t%s.set%s(%s.get%s());\n",
                        element.getText(), upperName, parameter.getName(), upperName));
            } else {
                sb.append(String.format("\t\t%s.set%s();\n", element.getText(), upperName));
            }
        }
        // 要插入的位置
        int endPos = primaryCaret.getVisualLineEnd();
        // 插入字符串
        WriteCommandAction.runWriteCommandAction(project, () ->
                document.insertString(endPos, sb.toString())
        );
    }
}
